%{
#include "ControlProxy.hpp"
%}

namespace kuai { namespace suan {

	class ControlProxy {
	public:
		virtual bool prepare(PyObject* self, PyObject* model, EnergySet& efunc) = 0;	
	};
	
} }


%{

namespace kuai { namespace suan {

	extern bool convertToControlSet(PyObject* model, EnergySet& efunc, PyObject* controls, 
		kuai::ControlSet& cset, std::vector<PythonControl*>& pycontrol) {

		Py_ssize_t n = PySequence_Size(controls);
		if (n < 0) {
			return false;
		}
		
		bool result = true;
		for (Py_ssize_t  i = 0; i < n; ++i) {
			PyObject* funcI = PySequence_GetItem(controls, i);
			assert (funcI != NULL);
			ControlProxy* p;
			int isOK =  SWIG_ConvertPtr(funcI, (void**)(&p), SWIGTYPE_p_kuai__suan__ControlProxy, 1);
			if (SWIG_IsOK(isOK)) {
				if (p->prepare(funcI, model, efunc)) {
					Py_DECREF(funcI);
					cset.funcs.push_back(p->func.get());
					continue;
				}
			}
			else {
				if (PyObject_HasAttrString(funcI, "start") ||
					PyObject_HasAttrString(funcI, "act") || 
					PyObject_HasAttrString(funcI, "finish"))
				{
					size_t period = 1;
					if (PyObject_HasAttrString(funcI, "period")) {
						PyObject* pp = PyObject_GetAttrString(funcI, "period");
						if (pp != NULL) {
							period = PyInt_AsSsize_t(pp);
							Py_DECREF(pp);
						}
						else {

						}
					}
					PythonControl* cp = new PythonControl(funcI, model, period);
					cp->period = period;
					pycontrol.push_back(cp);
					cset.funcs.push_back(pycontrol.back());
					continue;
				}
				else {
					PyErr_SetString(PyExc_NotImplementedError, "This function is not a control");
				}
			}
			Py_DECREF(funcI);
			result = false;
			break;
		}
		return result;
	}
} }
%}
